package com.jiankangjin.weixinchannel.services.impl;

import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.jiankangjin.common.json.jackson.JSONUtil;
import com.jiankangjin.weixinchannel.config.WeixinConfig;
import com.jiankangjin.weixinchannel.services.PayService;
import com.jiankangjin.weixinchannel.util.MD5Util;
import com.jiankangjin.weixinchannel.util.RequestHandler;
import com.jiankangjin.weixinchannel.util.Sha1Util;
import com.jiankangjin.weixinchannel.util.StringUtil;
import com.jiankangjin.weixinchannel.util.TenpayHttpClient;
import com.jiankangjin.weixinchannel.util.XMLUtil;
import com.jiankangjin.weixinchannel.vo.PayVo;

/**
 * 支付宝所有类型版本支付方法实现
 */
public class PayServiceImpl implements PayService {
	private static final transient Log logger = LogFactory.getLog(PayServiceImpl.class);

	/**
	 * 扫码付V0.0.1
	 */
	@Override
	public PayVo barcode_V0_0_1(String pay_ssn_id, String order_id,
			String pay_fee, String pay_cry, String buyer_token,
			String buyer_voucher, String subjet, String remark,
			String buyer_name, String buyer_email, String seller_name,
			String seller_email, String expand_json) {
		// 解开自定义参数
		String spbill_create_ip = "127.0.0.1";
		String _attach = "yjwkhhbj_secondsun_hello";
		if (expand_json != null && expand_json.indexOf(":") > 0) {
			@SuppressWarnings("unchecked")
			Map<String, String> expandMap = JSONUtil.fromJSON(expand_json,
					HashMap.class);
			if (expandMap != null) {
				spbill_create_ip = expandMap.get("spbill_create_ip");
				_attach = expandMap.get("attach");
			}
		}
		PayVo payVo = new PayVo();
		try {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("appid", WeixinConfig.APP_ID);
			params.put("mch_id", WeixinConfig.MCH_ID);
			params.put("sub_mch_id", "");//子商户号
			params.put("device_info", "1000");//终端设备号(商户自定义)
			params.put("nonce_str", Sha1Util.getNonceStr());//随机串
			params.put("body", "SHS_Test_goods");//商品描述
			params.put("attach", _attach);//附加数据，会被原样返回,自定义参数传入
			params.put("out_trade_no", pay_ssn_id);//商户订单号，在交易系统里，是支付记录ID
			params.put("total_fee", "1");//固定1分钱
			params.put("spbill_create_ip", spbill_create_ip);//订单生成的机器 IP,自定义参数传入
			params.put("time_start", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));//交易起始时间
			params.put("time_expire", "");//交易结束时间
			params.put("goods_tag", "");//商品标记
			params.put("auth_code", buyer_token);//扫码的码
			Map<String, Object> sPara = MD5Util.MD5Encode(params, "utf8");
			
			String xmlStr = XMLUtil.toXMLstr(sPara);

	    	logger.info("提交被扫支付 API:"+xmlStr);
			TenpayHttpClient httpClient = new TenpayHttpClient();
			String url = "https://api.mch.weixin.qq.com/pay/micropay";
			Map<String, String> weixinMap = null;
	    	if(httpClient.callHttpPost(url, xmlStr)) {
	    		weixinMap = XMLUtil.doXMLParse(new String(httpClient.getResContent().getBytes("gbk"), "utf8"));
	    		if (weixinMap == null) {
	    			weixinMap = new HashMap<String, String>();
	    			weixinMap.put("return_code", "SUCCESS");
	    			weixinMap.put("err_code_des", "等待用户输入支付密码");
	    			weixinMap.put("result_code", "FAIL");
	    			weixinMap.put("err_code", "USERPAYING");
				}
				logger.info("微信API返回:"+weixinMap);
	    	}
	    	if (weixinMap == null) {
				payVo.setResp_status("9999");
				payVo.setResp_msg("系统异常，渠道支付失败");
				return payVo;
			}
	    	if ("SUCCESS".equals(weixinMap.get("return_code"))) {//return_code 为 SUCCESS 的时候
	    		payVo.setSub_deal_msg(weixinMap.get("err_code_des"));
	    		payVo.setPay_chnl_mer(weixinMap.get("mch_id"));
	    		payVo.setPay_chnl_pos(weixinMap.get("device_info"));
	    		if ("SUCCESS".equals(weixinMap.get("result_code"))) {//return_code 和 result_code 都为 SUCCESS 的时候
	    			payVo.setSub_deal_status("1001");
					payVo.setSub_deal_msg("支付成功");
	    			payVo.setPay_user(weixinMap.get("openid"));
	    			payVo.setPay_chnl_seq(weixinMap.get("transaction_id"));
	    			payVo.setPay_fin_time(weixinMap.get("time_end"));
				} else {
					if ("USERPAYING".equals(weixinMap.get("err_code"))) {
						payVo.setSub_deal_status("0021");
						payVo.setSub_deal_msg(weixinMap.get("err_code_des"));
					} else {
						payVo.setSub_deal_status("0041");
						payVo.setSub_deal_msg("支付失败");
					}
					GetPayStateThread thread = new GetPayStateThread(pay_ssn_id, weixinMap.get("transaction_id"));
					thread.start();
					System.out.println("---------线程已启------------");
				}
			} else {
				payVo.setSub_deal_status("0041");
				payVo.setSub_deal_msg(weixinMap.get("return_msg"));
			}
	    	payVo.setPay_ssn_id(pay_ssn_id);
	    	payVo.setOrder_id(order_id);
	    	payVo.setPay_cry(pay_cry);
	    	payVo.setPay_fee(pay_fee);
	    	
	    	payVo.setResp_status("0000");
	    	payVo.setResp_msg("返回成功");
	    	payVo.setReturn_json("");
	    	payVo.setExpand_json(expand_json);
	    	payVo.setSign("WeixinChannel_barcode_V0_0_1_sign");
		} catch (Exception e) {
			payVo.setResp_status("9999");
			payVo.setResp_msg("系统报错");
			e.printStackTrace();
		}
		return payVo;
	}
/*
 * result_code=FAIL, 
 * sign=51F439047ACE673A5721B7701A50C6C9, 
 * mch_id=10017474, 
 * err_code=USERPAYING, 
 * err_code_des=�?��用户输入支付密码, 
 * return_msg=OK, 
 * appid=wxcec8863ae602c67c, 
 * nonce_str=lYa3II4AK9XcBknG, 
 * return_code=SUCCESS, 
 * device_info=1000
 */
	
	
	/**
	 * 公众号支付 V2
	 * 【微信支付】公众号支付接口文档V2.6
	 * 微信渠道的公众号支付,结果通过交易系统返回给微信网关.
	 */
	@Override
	public PayVo public_V2(String pay_ssn_id, String order_id, String pay_fee,
			String pay_cry, String buyer_token, String buyer_voucher,
			String subjet, String remark, String buyer_name,
			String buyer_email, String seller_name, String seller_email,
			String expand_json) {
        PayVo payVo = new PayVo();
		// 解开自定义参数
		String spbill_create_ip = "127.0.0.1";
		String orderamount = "W5G7E6REVE58UOUIL3UKYJH5CE468S57RDYD5T1";
		if (expand_json != null && expand_json.indexOf(":") > 0) {
			@SuppressWarnings("unchecked")
			Map<String, String> expandMap = JSONUtil.fromJSON(expand_json, HashMap.class);
			if (expandMap != null) {
				spbill_create_ip = expandMap.get("spbill_create_ip");
				orderamount = expandMap.get("orderamount");
			}
		}
		try {
			RequestHandler reqHandler = new RequestHandler();
	    	reqHandler.init(WeixinConfig.APP_ID, WeixinConfig.APP_SECRET, WeixinConfig.APP_KEY, WeixinConfig.PARTNER_KEY);
	    	
	    	//设置package订单参数
			SortedMap<String, String> packageParams = new TreeMap<String, String>();
			packageParams.put("bank_type", "WX");  //支付类型   
			packageParams.put("body", pay_ssn_id); //商品描述   
			packageParams.put("partner", WeixinConfig.PARTNER_ID); //设置商户号
			packageParams.put("out_trade_no", pay_ssn_id); //商户订单号  
			packageParams.put("total_fee", StringUtil.yuan2Fen(orderamount)+""); //商品总金额,以分为单位
			packageParams.put("fee_type","1"); 	  //银行币种
			packageParams.put("notify_url", WeixinConfig.NOTIFY_URL);
			packageParams.put("spbill_create_ip",  spbill_create_ip); //订单生成的机器IP，指用户浏览器端IP
			packageParams.put("input_charset", "GBK"); //字符集
			
			SortedMap<String, String> signParams = new TreeMap<String, String>();
			//获取package包
			String packageValue = reqHandler.genPackage(packageParams);
			String noncestr = Sha1Util.getNonceStr();
			String timeStamp = Sha1Util.getTimeStamp();
			//设置支付参数
			signParams.put("appid", WeixinConfig.APP_ID);
			signParams.put("noncestr", noncestr);
			signParams.put("package", packageValue);
			signParams.put("timestamp", timeStamp);
			signParams.put("appkey", WeixinConfig.APP_KEY);
			//生成支付签名，要采用URLENCODER的原始值进行SHA1算法！
			String signWx = Sha1Util.createSHA1Sign(signParams);
			
			Map<String, Object> returnMap = new HashMap<String, Object>();

			returnMap.put("appId", WeixinConfig.APP_ID);
	        returnMap.put("timeStamp", timeStamp);
	        returnMap.put("nonceStr", noncestr);
	        returnMap.put("package1", packageValue);
	        returnMap.put("signType", "SHA1");
	        returnMap.put("paySign", signWx);
	        
	        payVo.setExpand_json(JSONUtil.toJSON(returnMap, HashMap.class));
	        return payVo;
		} catch (UnsupportedEncodingException e) {
			logger.error("组建package数据异常", e);
		} catch (Exception e) {
			logger.error("异常", e);
		}
		return payVo;
	}

	/**
	 * 公众号V3
	 * 共众号统一支付接口:	/public_pay
	 * 对应微信接口：		https://api.mch.weixin.qq.com/pay/unifiedorder
	 * 微信支付v3.3.5版本
	 */
	@Override
	public PayVo public_V3(String pay_ssn_id, String order_id, String pay_fee,
			String pay_cry, String buyer_token, String buyer_voucher,
			String subjet, String remark, String buyer_name,
			String buyer_email, String seller_name, String seller_email,
			String expand_json) {
        PayVo payVo = new PayVo();
		// 解开自定义参数
		if (StringUtil.isEmpty(expand_json)|| expand_json.indexOf(":")<=0 ) {
			logger.error("订单扩展参数expand_json为空！");
			return payVo;
		}
		@SuppressWarnings("unchecked")
		Map<String, String> expandMap = JSONUtil.fromJSON(expand_json, HashMap.class);
		logger.info("expandMap="+expandMap);
		if (expandMap == null) {
			logger.error("订单扩展参数expand_json解析失败！");
			return payVo;
		}
		String _spbill_create_ip = expandMap.get("spbill_create_ip");
		String _attach = expandMap.get("attach");
		String _trade_type = expandMap.get("trade_type");
		String _openid = expandMap.get("openid");
		String _product_id = expandMap.get("product_id");
		
		// 验证参数
		if (StringUtil.isEmpty(_trade_type) ) {
			logger.error("trade_type为空");
			return payVo;
		}
		if (!"JSAPI".equals(_trade_type) && !"NATIVE".equals(_trade_type)) {
			logger.error("trade_type错误，必须为JSAPI或者NATIVE");
			return payVo;
		}
		if ("JSAPI".equals(_trade_type) && StringUtil.isEmpty(_openid)) {
			logger.error("trade_type为JSAPI,那么openid不能为空");
			return payVo;
		}
		if ("NATIVE".equals(_trade_type) && StringUtil.isEmpty(_product_id)) {
			logger.error("trade_type为NATIVE,那么product_id不能为空");
			return payVo;
		}

		try {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("appid", WeixinConfig.APP_ID);
			params.put("mch_id", WeixinConfig.MCH_ID);
//					params.put("sub_mch_id", "");// 子商户号
//					params.put("device_info", "1000");// 终端设备号(商户自定义)
			params.put("nonce_str", Sha1Util.getNonceStr());// 随机串
			params.put("body", "SHS_Test_goods");// 商品描述
			params.put("attach", _attach);// 附加数据，会被原样返回,自定义参数传入
			params.put("out_trade_no", pay_ssn_id);// 商户订单号，在交易系统里，是支付记录ID
			params.put("total_fee", "1");// 固定1分钱
			params.put("spbill_create_ip", _spbill_create_ip);// 订单生成的机器 IP,自定义参数传入
			Calendar c = Calendar.getInstance();
			DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
			params.put("time_start", df.format(c.getTime()));// 交易起始时间
			c.add(Calendar.DAY_OF_MONTH, 1);
			params.put("time_expire", df.format(c.getTime()));	// 交易结束时间
			params.put("goods_tag", "test_goods");	// 商品标记
			String notityurl = "http://payment-test.jiankangjin.com/weixinChannel/public_notify";
			params.put("notify_url", notityurl);//WeixinConfig.NOTIFY_URL);
			params.put("trade_type", _trade_type);	// JSAPI、NATIVE、APP
			if (_trade_type.equals("JSAPI")) {
				params.put("openid", _openid);		//trade_type 为 JSAPI 时，此参数必传
			}
			if(_trade_type.equals("NATIVE")) {
				params.put("product_id", _product_id);	// trade_type 为 NATIVE 时需要填写
			}
			Map<String, Object> sPara = MD5Util.MD5Encode(params, "utf8");

			String xmlStr = XMLUtil.toXMLstr(sPara);

	    	logger.info("调微信统一支付接口:"+xmlStr);
			TenpayHttpClient httpClient = new TenpayHttpClient();
			String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
			Map<String, String> weixinMap = new HashMap<>();
	    	if(httpClient.callHttpPost(url, xmlStr)) {
	    		weixinMap = XMLUtil.doXMLParse(new String(httpClient.getResContent().getBytes("gbk"), "utf8"));
				logger.info("微信API返回:"+weixinMap);
	    	}
	    	String prepayId = weixinMap.get("prepay_id");
	    	if(StringUtil.isEmpty(prepayId)){
				logger.error("预下单失败");
				return payVo;
	    	}
	    	//获取package包
	    	String packageValue = "prepay_id=" + weixinMap.get("prepay_id");
			String noncestr = Sha1Util.getNonceStr();
			String timeStamp = Sha1Util.getTimeStamp();
			//设置支付参数
			Map<String, String> returnMap = new HashMap<String, String>();
			SortedMap<String, Object> signParams = new TreeMap<String, Object>();
			signParams.put("appId", WeixinConfig.APP_ID);
			signParams.put("timeStamp", timeStamp);
			signParams.put("nonceStr", noncestr);
			signParams.put("package", packageValue);
			String signType = "MD5";
			signParams.put("signType", signType);
//					signParams.put("appkey", WeixinConfig.APP_KEY);
			
			//生成支付签名
//					String signWx = Sha1Util.createSHA1Sign(signParams);
			String signWx = MD5Util.MD5Encode(signParams);

			returnMap.put("appId", WeixinConfig.APP_ID);
	        returnMap.put("timeStamp", timeStamp);
	        returnMap.put("nonceStr", noncestr);
	        returnMap.put("package1", packageValue);
	        returnMap.put("signType", signType);
	        returnMap.put("paySign", signWx);
	        logger.info("------调完微信渠道后签名数据给网关----\n"
	        		+ returnMap
	        		+ "------------------------\n");
	        payVo.setOrder_id(order_id);
	        payVo.setPay_cry("156");
	        payVo.setPay_fee(pay_fee);
	        payVo.setPay_fin_time(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
	        payVo.setPay_ssn_id(pay_ssn_id);
	        payVo.setResp_status("0000");
	        payVo.setResp_msg("成功");
	        payVo.setSign("weixinChannel_public_V3_sign");
	        payVo.setSub_deal_status("0021");
	        payVo.setSub_deal_msg("用户正在支付");
	        payVo.setExpand_json(JSONUtil.toJSON(returnMap, HashMap.class));
	        return payVo;
		} catch (Exception e) {
			logger.trace("微信渠道支付过程中发生异常！", e);
			e.printStackTrace();
		}
		return payVo;
	}


}
